#ifndef GLOBAL_DEFINE_H_
#define GLOBAL_DEFINE_H_

/*头文件*/
#include <semaphore.h>								//< 信号量头文件
#include <fcntl.h>									//< 信号量头文件
#include <stdio.h>
#include <dlfcn.h>
#include <Python.h>
#include <sys/syscall.h>							//< duan20200609添加
#include <sys/types.h>								//< duan20200609添加
#include <unistd.h>									//< duan20200609添加

/*全局可调参变量*/
#define SCHED_POLICY				SCHED_RR		//< 线程调度方式
#define CONTROL_CORE				CPU_CORE1		//< 控制CPU采用哪个核进行运算			//< duan20200404测试 由CPU_COREANY 更替为 
#define TIMER_PRIORITY				90				//< 定时器中断信号处理线程的优先级
#define DEL_FILE_STATION_START		true			//< 开机删除文件标志（true为删除；false为不删除）
#define START_ON_LOCAL				true			//< 是否本地启动（true为本地启动，false为非本地启动）
#define DCS_TIMEOUT_MAXNUM			4				//< 接收DCS广播超时次数
#define IOCARD_MAX_NUM				1024		    //< lijun20220723 指的通讯时不同从站(IP+端口不同)卡件的最大数目，因大有卡件数大幅上升，由64提至1024
#define IP_STR_LENGTH				16				//< Shike20210515 保存IP地址的char数组长度，因为最多12位数字和三个小数点和最后\0，总共16
#define SAMA_PGE_MAX				512				//< 最大SAMA页数
#define SAMA_MODEL_MAXNUM			10000			//< 最大SAMA模块数量
#define PRINTF_REPOINT				false			//< 串口重定向（true-重定向；false-不重定向）
#define MASTER_SLAVE_ID_DT			50				//< 主从站站号差值
#define SAMAIO_CARD_ID				0				//< SAMA软点所在卡件的ID号（需要与上位协商一致）
//#define IS_USE_LANB								//< 是否启用1网段，如果启用，则定义该宏定义，如不启用，注释该行

/*目标机设备描述符*/
#define NETWORK_CARD_A				"eth0"	 		//< 该网口跑0网段（192.168.0.XXX），IP末尾根据站号决定，由读取txt文件获取		//<  duan1117 工控机为eth0 
#define NETWORK_CARD_B				"eth2"	 		//< 该网口跑1网段（192.168.1.XXX），IP末尾根据站号决定，由读取txt文件获取，由于只有两个网口，所以该网段暂时不做开发
#define NETWORK_CARD_BAKORDEBUG		"eth1"	 		//< 该网口跑2网段（192.168.2.XXX），该网段用于主从站备份及VS2017远程调试，因此IP末尾为0或1，站号小于100的为0，站号大于100的为1   //< duan1117 工控机为eth1
#define PORT_DEBUG					"/dev/ttyS0"	//< 打印调试信息的串口
#define PORT_PSSWITCH				"/dev/ttyS1"	//< 主从站状态检测串口		//< duan1117 工控机上为"/dev/ttyS1" 给浙江电科院时务必改过来				实验室为/dev/ttyS0
#define PORT0_485					"/dev/ttyS2"	//< 485通讯串口1			//< duan0515 和lww485串口名不一致    修改
#define PORT1_485					"/dev/ttyS3"	//< 485通讯串口2


/*网络通讯端口号*/
#define MODBUSTCP_PORT				502				//< MODBUSTCP通讯端口号
#define BCSAMA_PORT					2667			//< 广播SAMA端口号
#define CMD_PORT					2668			//< 接收上位命令字端口号
#define DOWN_CMD_PORT				2669			//< 接收上位下装命令字端口号
#define BCDPU_PORT					2672			//< 广播DPU状态端口号
#define BCNIC_PORT					2674			//< 广播NIC状态端口号
#define BCSAMAIO_PORT				2802			//< 广播软点端口号
#define BCIO_PORT					2800			//< 广播硬点端口号
#define BCSAMAPARA_PORT				2750			//< 广播SAMA模块参数端口号
#define RECVDCSBC_PORT				2730			//< 接收DCS广播端口号
#define BCNETIO_PORT				2671			//< 站间引用点广播端口号
#define	RECVNETIOBC_PORT			BCNETIO_PORT	//< 接收站间引用点广播的端口号
#define BAKDATA_PORT				4868			//< 主站向从站备份数据端口号
#define RECVBAKDATA_PORT			BAKDATA_PORT	//< 从站接收主站备份的数据端口号
#define BAKIO_PORT					4870			//< 主站向从站备份IO硬点数据端口号
#define RECVBAKIO_PORT				BAKIO_PORT		//< 从站接收主站备份的IO硬点数据端口号
#define SETTIME_PORT				9500			//< 对时功能端口
#define IEC104TCP_EXTRA_PORT1	    2405			//< 104规约通讯端口号主站使用额外端口1
#define IEC104TCP_EXTRA_PORT6	    2406			//< 104规约通讯端口号主站使用额外端口2
#define PSS_PORT                    9502            //< 主从判断端口号
#define IEC104TCP_PORT				2404			//< 104规约通讯端口号(子站端口号 <指的是16控制平台做从站时所用的本地端口号>)    
													//< Shike20210328 在长兴现场 因为104从站一台电脑连我们两台工控机两个主站，所以
																	//< 两台工控机对应不同端口 一个2404 一个2405

 

/*定时周期设置（单位ms）*/
#define BCDPU_PERIOD				500				//< 广播DPU状态周期
#define BCNIC_PERIOD				500				//< 广播NIC状态周期
#define BCSAMAIO_PERIOD				1000				//< 广播软点周期
#define READSAMAIO_PERIOD			1000			//< 读取sama软点周期
#define BCAVIO_PERIOD				1000				//< 广播模拟量硬点周期
#define BCDVIO_PERIOD				1000				//< 广播数字量硬点周期
#define BCSAMA_PERIOD				500				//< 广播SAMA周期
#define BCSAMAPARA_PERIOD			1000			//< 广播SAMA参数周期
#define TEST_DCS_TIMEOUT_PERIOD		30000			//< DCS广播超时检测周期
#define BAKDATA_PERIOD				1000			//< 主从站备份周期
#define BAKIO_PERIOD				1000			//< 主从站备份IO硬点周期
#define BCNETIO_PERIOD				500				//< 站间引用点广播周期
//#define IEC104CALLALL_PERIOD		900000			//< IEC104主站通讯总召唤周期
//#define IEC104CLOCK_PERIOD		1200000			//< IEC104主站通讯对时周期

/*网络通讯网址*/
#define STATION_IP_TAIL_NUM			2				//< 非本地启动的时候控制站的IP地址
#define NETA_IP_BC				"192.166.100.255"	//< 100网段全局广播地址
#define NETB_IP_BC				"192.166.101.255"	//< 101全局广播地址
//#define NETC_IP_BC				"192.166.2.255"	//< 2网段全局广播地址    （用于主从站备份）

//lijun20220706 主备身份判断更改为双主双备 
												  //交流IP         贾汪后边这一块取消使用（之前192.166.3.1是大有直流控制器，192.166.3.2是交流控制器）
#define NETD_PSS_BC_1		((IPTail_Num ==66) ? ("192.166.3.1"):("192.166.3.2"))//主
#define NETD_PSS_BC_2		((IPTail_Num ==16) ? ("192.166.3.51"):("192.166.3.52"))//备
#define NETD_PSS_BC			((IPTail_Num<MASTER_SLAVE_ID_DT) ? NETD_PSS_BC_2:NETD_PSS_BC_1)	//< 3网段全局广播地址   （用于主从身份判断）

//lijun20220706 主备备份更改为双主双备
												   //交流IP         
#define NETC_PSS_BC_1		((IPTail_Num ==66) ? ("192.166.2.1"):("192.166.2.2"))//主机
#define NETC_PSS_BC_2		((IPTail_Num ==16) ? ("192.166.2.51"):("192.166.2.52"))//备站
#define NETC_IP_BC			((IPTail_Num<MASTER_SLAVE_ID_DT) ? NETC_PSS_BC_2:NETC_PSS_BC_1)	

#define SETTIME_IP					"192.166.100.26"	//< 对时功能IP地址
#define NETA_NAME					"192.166.100."	//< A网段IP地址
#define NETB_NAME					"192.166.101."	//< B网段IP地址
#define NETC_NAME					"192.166.2."	//< C网段IP地址

//lijun20220706 更改为双主双备
//主站                                                    //直流IP               交流IP
#define CONTROL1_NETA_LOCAL_IP		((IPTail_Num ==16) ? ("192.166.100.16") : ("192.166.100.17"))	//< 控制器1的100网段本地地址
#define CONTROL1_NETB_LOCAL_IP		((IPTail_Num ==16) ? ("192.166.101.16") : ("192.166.101.17"))//< 控制器1的101网段本地地址
#define CONTROL1_IEC_104_MASTER_IP1 ((IPTail_Num ==16) ? ("192.166.100.201") : ("192.166.100.202"))//< 控制器1做主站时104通讯的地址1，104协议指定客户端的ip地址 （A网段）
#define CONTROL1_IEC_104_MASTER_IP2 ((IPTail_Num ==16) ? ("192.166.100.28") : ("192.166.100.22"))    //< 控制器1做主站时104通讯的地址2，104协议指定客户端的ip地址 （B网段）
#define CONTROL1_IEC_104_MASTER_NET ((Net_Chosen == NETA) ? (CONTROL1_IEC_104_MASTER_IP1) : (CONTROL1_IEC_104_MASTER_IP2))//控制器1做104主站时通讯用的本地IP

//lijun20220706 更改为双主双备
//备站													//直流IP                交流IP
#define CONTROL2_NETA_LOCAL_IP		((IPTail_Num ==66) ? ("192.166.100.66"):("192.166.100.67"))	//< 控制器2的100网段本地地址
#define CONTROL2_NETB_LOCAL_IP		((IPTail_Num ==66) ? ("192.166.101.66"):("192.166.101.67"))	//< 控制器2的101网段本地地址
#define CONTROL2_IEC_104_MASTER_IP1 ((IPTail_Num ==66) ? ("192.166.100.251"):("192.166.100.252"))    //< 控制器2做主站时104通讯的地址1，104协议指定客户端的ip地址 （A网段）
#define CONTROL2_IEC_104_MASTER_IP2 ((IPTail_Num ==66) ? ("192.166.100.27"):("192.166.100.24"))    //< 控制器2做主站时104通讯的地址2，104协议指定客户端的ip地址 （B网段）
#define CONTROL2_IEC_104_MASTER_NET ((Net_Chosen == NETA) ? (CONTROL2_IEC_104_MASTER_IP1) : (CONTROL2_IEC_104_MASTER_IP2))//控制器2做104主站时通讯用的本地IP

#define IEC_104_MASTER_NET ((IPTail_Num <MASTER_SLAVE_ID_DT) ? (CONTROL1_IEC_104_MASTER_NET) : (CONTROL2_IEC_104_MASTER_NET))  //主站通讯用的本地IP
#define NETA_IP_BC_LOCAL ((IPTail_Num <MASTER_SLAVE_ID_DT) ? (CONTROL1_NETA_LOCAL_IP) : (CONTROL2_NETA_LOCAL_IP))              //广播时100网段需要绑定的本地IP    （1/ETH3）
#define NETB_IP_BC_LOCAL ((IPTail_Num <MASTER_SLAVE_ID_DT) ? (CONTROL1_NETB_LOCAL_IP) : (CONTROL2_NETB_LOCAL_IP))              //广播时101网段需要绑定的本地IP    （2/ETH2）
#define NETD_IP_BC_LOCAL ((IPTail_Num <MASTER_SLAVE_ID_DT) ? (CONTROL1_IEC_104_MASTER_IP1) : (CONTROL2_IEC_104_MASTER_IP1))    //广播时104通讯网卡需要绑定的本地IP（3/ETH0）
#define LOCAL_IP ((IPTail_Num <MASTER_SLAVE_ID_DT) ? (CONTROL1_NETA_LOCAL_IP) : (CONTROL2_NETA_LOCAL_IP))    //广播时104通讯网卡需要绑定的本地IP（3/ETH0）

/*FTP全局宏定义*/
#define FTP_NAME					"lww"			//< ftp传输用户名
#define FTP_PASSWD					"jade_311"			//< ftp传输密码


/*全局文件路径定义*/
#define IP_FILE_PATH				"/home/lww/IP.txt"					//< 目标机存放本地启动IP地址的文件路径
#define DOWN_FILE_PATH				"/home/lww/mytffs"					//< 下装文件存放文件夹
#define SAMA_FILE_PATH				"/home/lww/mytffs/Chart.ps"			//< SAMA文件存放路径
#define DATA_FILE_PATH				"/home/lww/mytffs/DataConfig.d"		//< DATA文件存放路径
#define TEMP_FILE_PATH				"/home/lww/mytffs/temp.tmp"			//< TEMP临时文件存放路径（该文件标记上位给主站的SAMA与DATA文件是否传输完成）
#define MASTER_SEND2_SALVE_TEMP_FILE_PATH		"/home/lww/mytffs/M2Stemp.tmp"	//< Shike20210516 主站给从站FTP发送的临时文件，标记数据库和SAMA发送完毕
#define USERDEF_MODULE_FILE_PATH	"/home/lww/myso/"					//< 用户自定义算法块文件路径
#define DMC_TAKE_SAMPLE_FILE_PATH	"/home/lww/mydmc/"					//< DMC和FFDMC模块生成的阶跃模型采样文件下装目录
#define TS_FILE_PATH				"/home/lww/myTS"					//<	调整时间Ts指标计算模块生成的文件存放目录
#define ATTRATE_FILE_PATH			"/home/lww/myATTRATE"				//< 衰减率指标计算ATTRATE模块生成的文件存放目录
#define AIGETFILE_FILE_PATH			"/home/lww/myAIGetFile"				//< 数据采集模块生成的文件存放目录
#define _104PORT_FILE_PATH			"/home/lww/104port.txt"				//< Shike20210328 在长兴现场 因为104从站一台电脑连我们两台工控机两个主站，所以两台工控机对应不同端口 一个2404 一个2405 通过读文件来确定104端口，而不是宏定义
#define GATEWAY_FILE_PATH			"/home/lww/gateway.txt"				//< Shike20210328 设置网关的文件
#define ETH0_CONFIGURATION          "/home/lww/LAN_configuration/eth0.txt"
#define ETH1_CONFIGURATION          "/home/lww/LAN_configuration/eth1.txt"
#define ETH2_CONFIGURATION          "/home/lww/LAN_configuration/eth2.txt"
#define ETH3_CONFIGURATION          "/home/lww/LAN_configuration/eth3.txt"
#define LoadForecastShortFile_PATH_HEAD  "/home/lww/LoadForecastShort/ZDDYFD_"//短期文件的头尾之间只有年月日，格式：20220122
#define LoadForecastShortFile_PATH_TAIL  "_0000_DQ.WPD"
#define LoadForecastUltraShortFile_PATH_HEAD  "/home/lww/LoadForecastUltraShort/ZDDYFD_"//超短期文件的头尾之间有年月日_时分，格式：20220121_2015
#define LoadForecastUltraShortFile_PATH_TAIL  "_CDQ.WPD"
#define UnderLine            "_"
#define COUNTFILE_PATH               "/home/lww/countfile/"

/*打印调试信息选项*/
#define PRINTF_DEBUG_MSG true
#define MY_PRINT(name) {if(PRINTF_DEBUG_MSG == true) printf(name);}


/*全局功能性宏定义*/
#define STR_NAME(name)	#name						//< 变量转字符串
#define MS2NS(name)	name*1000000					//< 毫秒转纳秒
#define MS2US(name)	name*1000						//< 毫秒转微妙


/*系统角色枚举定义*/
typedef enum {
	Default_Role = 0,								//< 未定义
	Master_Alone_Role,								//< 角色为主站，且备站不存在
	Master_Twins_Role,								//< 角色为主站，且备站存在
	Slave_Role										//< 角色为从站
}SYS_Role_e;


/*系统状态枚举定义*/
typedef enum {
	Default_Status = 0,								//< 离线状态
	Run_Status = 2,									//< 正常运行状态
	File_Transfer_Status,							//< 主从文件拷贝状态
	File_Wait_Status,								//< 等待文件状态
	Forbid_Commend_Status							//< 禁止命令下发状态
}SYS_Status_e;


/*网段状态枚举定义*/
typedef enum {
	Net_Trouble = 0,								//< 网络故障
	Net_Normal										//< 网络正常
}NET_Status_e;

/*网段状态枚举定义*/
typedef enum {
	NIC_Trouble = 0,								//< 网络故障
	NIC_Normal										//< 网络正常
}NIC_Status_e;


/*系统定时中断信号枚举*/
typedef enum {
	BcDPUSIG = 0,									//< 广播DPU状态定时信号
	BcNetIOSIG,										//< 广播站间通讯模块DO、AO数据定时信号
	CalcuSIG,										//< SAMA运算定时信号
	BcAVIOSIG,										//< 广播模拟量硬点定时信号
	BcDVIOSIG,										//< 广播数字量硬点定时信号
	BcSamaIOSIG,									//< 广播软点定时信号
	ReadSamaIOSIG,									//< 读取SAMA软点信号
	BcSamaSIG,										//< 广播SAMA定时信号
	BcSamaParaSIG,									//< 广播SAMA参数定时信号
	BakDataSIG,										//< 主站向从站备份数据定时信号
	BakIOSIG,										//< 主站向从站备份IO硬点数据定时信号
	TestDCSTimeOutSIG,								//< 检测DCS离线定时信号
	IEC104CallAllSIG,								//< IEC104主站通讯总召唤定时信号
	IEC104ClockSIG									//< IEC104主站通讯对时定时信号
}Timer_SIG;


/*IO通道数量结构体*/ //老版是char（李） 新版是short（郑）
typedef struct {
	unsigned short AI_Num;							//< 模拟量输入引脚数量
	unsigned short DI_Num;							//< 数字量输入引脚数量
	unsigned short AO_Num;							//< 模拟量输出引脚数量
	unsigned short DO_Num;							//< 数字量输出引脚数量
}IO_Num_t;

typedef struct {
	unsigned char AI_Num;							////< SAMA模块模拟量输入引脚数量
	unsigned char DI_Num;							////< SAMA模块数字量输入引脚数量
	unsigned char AO_Num;							////< SAMA模块模拟量输出引脚数量
	unsigned char DO_Num;							////< SAMA模块数字量输出引脚数量
}SAMA_Model_IO_Num_t;

/*互斥体定义*/
//extern pthread_mutex_t BakData_Mutex;					//< 主站定时向从站备份信号量
//extern pthread_mutex_t BakIO_Mutex;					//< 主站定时向从站备份IO硬点信号量
//extern pthread_mutex_t BcDPU_Mutex;					//< 主站定时广播DPU状态信号量
//extern pthread_mutex_t BcAVIO_Mutex;					//< 主站定时广播模拟量硬点信号量
//extern pthread_mutex_t BcDVIO_Mutex;					//< 主站定时广播数字量硬点信号量
//extern pthread_mutex_t BcSama_Mutex;					//< 主站定时广播SAMA参数信号量
//extern pthread_mutex_t BcSamaIO_Mutex;				//< 主站定时广播SAMA软点信号量
//extern pthread_mutex_t ReadSamaIO_Mutex;				//< 读取软点信号量
//extern pthread_mutex_t BcSamaPara_Mutex;				//< 主站定时广播SAMA模块参数信号量
//extern pthread_mutex_t BcNetIO_Mutex;					//< 主站定时广播站间通讯模块DO、AO数据信号量
//extern pthread_mutex_t Calcu_Mutex;					//< 各运算周期定时运算信号量

//extern pthread_mutex_t IEC104_CallAll_Mutex;			//< IEC104主站通讯定时发送总召唤信号量
//extern pthread_mutex_t IEC104_Clock_Mutex;			//< IEC104主站通讯定时发送对时信号量

//< duan 20200205修改
/*信号量定义*/
extern sem_t* BakDataSemId;							//< 主站定时向从站备份信号量
extern sem_t* BakIOSemId;							//< 站定时向从站备份IO硬点信号量
extern sem_t* BcDPUSemId;							//< 主站定时广播DPU状态信号量
extern sem_t* BcAVIOSemId;							//< 主站定时广播模拟量硬点信号量
extern sem_t* BcDVIOSemId;							//< 主站定时广播数字量硬点信号量
extern sem_t* BcSamaSemId;							//< 主站定时广播SAMA参数信号量
extern sem_t* BcSamaIOSemId;						//< 主站定时广播SAMA软点信号量
extern sem_t* ReadSamaIOSemId;						//< 读取软点信号量
extern sem_t* BcSamaParaSemId;						//< 主站定时广播SAMA模块参数信号量
extern sem_t* BcNetIOSemId;							//< 主站定时广播站间通讯模块DO、AO数据信号量
extern sem_t* CalcuSemId;							//< 各运算周期定时运算信号量

/*系统状态全局变量定义*/
extern SYS_Role_e SYS_Role;							//< 系统角色（未定义、主站且备站不存在、主站且备站存在、备站）
extern SYS_Status_e SYS_Status;						//< 系统状态（离线、正常运行、主从文件拷贝、等待文件、禁止命令下发）
extern NET_Status_e SYS_NetA_Status;				//< A网段状态（故障、正常）
extern NET_Status_e SYS_NetB_Status;				//< B网段状态（故障、正常）
extern NET_Status_e SYS_NetD_Status;				//< B网段状态（故障、正常）
extern bool SYS_ReadCard_Start;						//< 开始执行读卡线程（True/false）
extern bool SYS_Calcu_Start;						//< 开始执行运算线程（True/false）
extern bool SYS_BcORBak_Start;						//< 开始执行广播及备份线程（True/false）
extern short SYS_BaseTime;							//< 站基准周期，由上位下发得到(ms)
extern unsigned char Station_ID;					//< 站号
extern unsigned char IPTail_Num;					//< IP地址最后一位
extern int DCS_TimeOut_Count;						//< DCS广播超时计数
extern bool SYS_SAMAIO_Start;						//< 开始执行SAMAIO通道写入线程（True/false）

//extern timespec BCIO_begin;     //< lijun20220723 测104通讯迟延 (发送)
//extern timespec BCIO_end;     //< lijun20220723 测104通讯迟延 (接收) 
//extern bool BCIO_flag;

/*函数定义*/
void SYS_Role_Turn(SYS_Role_e role);					//< 系统角色切换并打印
void SYS_Status_Turn(SYS_Status_e status);				//< 系统状态切换并打印
char* Int2String(int num, char* str, int radix);		//< 整数转化为字符串

#endif